package own.stu.jobgib.playown.alg.leetcode.editor.cn.demo;/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

import own.stu.jobgib.playown.alg.leetcode.editor.cn.ListNode;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class Solution {

    public static void main(String[] args) throws InterruptedException {
        Solution solution = new Solution();

        /*ListNode head = new ListNode(1,
                new ListNode(2,
                        new ListNode(3,
                                new ListNode(3, new ListNode(4, new ListNode(4, new ListNode(5)))))));
        ListNode res = solution.deleteDuplicates(head);
        System.out.println(res);*/

        /*int search = solution.search(new int[]{1, 2, 3, 4, 6, 8}, 8);
        System.out.println(search);*/

        /*ArrayList<Integer> arrayList = solution.maxInWindows(new int[]{2, 3, 4, 2, 6, 2, 5, 1}, 3);
        System.out.println(arrayList);*/

        ExecutorService executorService = Executors.newFixedThreadPool(4);
        executorService.submit(() -> {
            System.out.println("------");
        });

        TimeUnit.SECONDS.sleep(3);
        executorService.submit(() -> {
            System.out.println("------");
        });
    }

    public ArrayList<Integer> maxInWindows(int[] num, int size) {
        ArrayList<Integer> ans = new ArrayList<>();
        if (num == null || num.length == 0) {
            return ans;
        }

        int n = num.length;
        Deque<Integer> stack = new LinkedList<>();
        for (int i = 0; i < size; i++) {
            addEle(stack, num, i);
        }

        for (int i = size; i < n; i++) {
            removeEle(stack, num, i - size);
            addEle(stack, num, i);
            ans.add(num[stack.getLast()]);
        }

        return ans;
    }

    private void addEle(Deque<Integer> stack, int[] num, int eleIdx) {
        while (!stack.isEmpty() && num[stack.peek()] < num[eleIdx]) {
            stack.pop();
        }
        stack.push(eleIdx);
    }

    private void removeEle(Deque<Integer> stack, int[] num, int eleIdx) {
        if (!stack.isEmpty() && num[stack.getLast()] == num[eleIdx]) {
            stack.removeLast();
        }
    }

    public int search(int[] nums, int target) {
        // write code here
        if (nums == null || nums.length == 0) {
            return -1;
        }
        int n = nums.length, l = 0, r = n - 1;
        while (l + 1 < r) {
            int mid = ((r - l) >> 1) + l;
            System.out.println(nums[mid] + " - " + l + " ---" + mid + " -- " + r);
            if (nums[mid] == target) {
                return mid;
            } else if (nums[mid] < target) {
                l = mid;
            } else {
                r = mid;
            }
        }
        if (nums[l] == target) return l;
        if (nums[r] == target) return r;
        return -1;
    }

    /**
     * 描述
     * 给出一个升序排序的链表，删除链表中的所有重复出现的元素，只保留原链表中只出现一次的元素。
     * 1→2→3→3→4→4→5, 返回 1→2→5.
     *
     * @param head ListNode类
     * @return ListNode类
     */
    public ListNode deleteDuplicates(ListNode head) {

        if (head == null) {
            return head;
        }

        ListNode dummy = new ListNode();
        dummy.next = head;
        ListNode pre = dummy;
        ListNode cur = dummy.next;
        while (cur != null) {
            ListNode nextNode = lastDupNode(cur);

            if (nextNode == null) {
                // break;
                pre = pre.next;
                cur = cur.next;

            } else {
                System.out.println(" -- " + nextNode.val);
                cur = nextNode.next;
                pre.next = cur;
            }
        }
        return dummy.next;
    }

    private ListNode lastDupNode(ListNode node) {
        if (node == null) {
            return node;
        }

        ListNode cur = node;
        ListNode next = cur.next;
        boolean dup = false;
        while (cur != null && next != null) {
            if (cur.val == next.val) {
                cur = cur.next;
                next = cur.next;
                dup = true;
            } else {
                break;
            }
        }
        return dup ? cur : null;
    }
}